package com.gmail.dengtao.joe.group.transport.impl;

import com.gmail.dengtao.joe.group.channel.Channel;
import com.gmail.dengtao.joe.group.interceptor.InterceptorStack;
import com.gmail.dengtao.joe.group.member.Member;
import com.gmail.dengtao.joe.group.transport.impl.handler.ChannelSenderHandler;
import com.gmail.dengtao.joe.transport.SocketMultiConnector;

public class TCPChannelSender extends AbstractChannelSender {

	private SocketMultiConnector connector = null;	// 
	protected ChannelSenderHandler handler = null;
	private final Object startLock = new Object();
	
	private Member local;

	public TCPChannelSender(String host, int port, Channel channel) throws Exception {
		this.channel = channel;
		local = new Member(host, port);
		connector = new SocketMultiConnector();
		handler = new ChannelSenderHandler(channel, local);
		
		connector.init();
	}

	@Override
	public void start(final Object senderLock) throws Exception {
		synchronized (startLock) {
			if (start) {
				throw new IllegalStateException("This receiver has already been started!");
			} else {
				start = true;
			}
			handler.setIdleTimeForWrite(idleTimeForWrite);
			handler.setInterceptorStack(interceptorStack);
			
			connector.setHandler(handler);
		}
		if (senderLock != null) {
			synchronized (senderLock) {
				senderLock.notifyAll();
			}
		}
		connector.connect();
	}

	@Override
	public void stop() throws Exception {
		connector.close();
		start = false;
	}
	
	@Override
	public void connect(Member target) throws Exception {
		synchronized (startLock) {
			connector.open(target.getHost(), target.getPort());
		}
	}
	
	@Override
	public void send(Member target, Object data) {
		if (start) handler.send(target, data);
	}
	
	@Override
	public void setSelectTimeout(int selectTimeout) {
		super.setSelectTimeout(selectTimeout);
		connector.setSelectTimeout(selectTimeout);
	}

	@Override
	public void setIdleTimeForWrite(int idleTimeForWrite) {
		super.setIdleTimeForWrite(idleTimeForWrite);
		handler.setIdleTimeForWrite(idleTimeForWrite);
	}

	@Override
	public void setSendBufferSize(int sendBufferSize)
			throws IllegalArgumentException {
		//super.setSendBufferSize(sendBufferSize);
	}

	@Override
	public void setInterceptorStack(InterceptorStack interceptorStack) {
		super.setInterceptorStack(interceptorStack);
		handler.setInterceptorStack(interceptorStack);
	}

}